package server

import (
	"chitchat_http/model"
	"chitchat_http/util"
	"errors"
	"fmt"
	"github.com/doujunyu/gogo/gogo_log"
	"github.com/doujunyu/gogo/sql_aid"
	"github.com/doujunyu/gogo/utility"
	"os"
	"strings"
	"time"
)

// ChatByList 聊天列表
func ChatByList(userId int64, page string, pageSize string) []map[string]interface{} {
	userMessageSql, args := sql_aid.PgTable(model.TableByUserMessage).Where("user_id = ?", userId).OrderBy("time_u desc").PageSize(page, pageSize).ToSql()
	userMessageData, err := sql_aid.DataToMap(model.PgSql.Query(userMessageSql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyList", "查询数据失败", err.Error())
		return []map[string]interface{}{}
	}
	userIds := make([]interface{}, 0)
	groupIds := make([]interface{}, 0)
	chatMessageLog := make([]interface{}, 0)
	for _, datum := range userMessageData {
		switch datum["type_id"].(int64) {
		case model.UserMessageByTypeIdFriend:
			userIds = append(userIds, datum["received_id"], datum["by_user_id"])
			//userIds = append(userIds)
		case model.UserMessageByTypeIdGroup:
			groupIds = append(groupIds, datum["received_id"])
		}
		chatMessageLog = append(chatMessageLog, datum["chat_message_log_id"])
	}
	//找出对应的用户数据
	userIdsByData := model.UserByIdsToDataP(&userIds)
	groupIdsByData := model.ChatGroupToData(groupIds...)
	chatMessageLogData := model.ChatMessageLogToData(chatMessageLog...)
	for _, datum := range userMessageData {
		datum["user"] = userIdsByData[datum["received_id"].(int64)]
		if datum["type_id"].(int64) == model.UserMessageByTypeIdGroup {
			datum["group"] = groupIdsByData[datum["received_id"].(int64)]
		} else {
			datum["group"] = nil
		}
		datum["chat_message_log"] = chatMessageLogData[datum["chat_message_log_id"].(int64)]
		datum["by_user"] = userIdsByData[datum["by_user_id"].(int64)]
	}
	return userMessageData
}

// ChatBySearchFriend 搜索好友
func ChatBySearchFriend(userId int64, search string, page string, pageSize string) []map[string]interface{} {
	//根据账号搜索
	usernameSql, arge := sql_aid.PgTable(model.TableByUserLogin).Field("user_id").Where("username like ?", search+"%").ToSql()
	usernameData, err := sql_aid.DataToMap(model.PgSql.Query(usernameSql, arge...))
	if err != nil {
		gogo_log.Error("server_ChatBySearchFriend", "查询数据失败", err.Error())
		return []map[string]interface{}{}
	}

	usernameByUserId := util.ArrayField(&usernameData, "user_id")
	//根据昵称搜索
	nickSql, arge := sql_aid.PgTable(model.TableByUser).Field("id", "nick", "avatar", "motto").Where("nick like ?", search+"%").ToSql()
	nackData, err := sql_aid.DataToMap(model.PgSql.Query(nickSql, arge...))
	if err != nil {
		gogo_log.Error("server_ChatBySearchFriend", "查询数据失败", err.Error())
		return []map[string]interface{}{}
	}
	nickByUserId := util.ArrayField(&nackData, "id")
	usernameByUserId = append(usernameByUserId, nickByUserId...)
	userSql, arge := sql_aid.PgTable(model.TableByUser).Field("id", "nick", "avatar", "motto").WhereIn("id", usernameByUserId...).PageSize(page, pageSize).ToSql()
	userData, err := sql_aid.DataToMap(model.PgSql.Query(userSql, arge...))
	if err != nil {
		gogo_log.Error("server_ChatBySearchFriend", "查询数据失败", err.Error())
		return []map[string]interface{}{}
	}

	//处理是否已经是好友的信息
	userIds := util.ArrayField(&userData, "id")
	userFriendSql, arge := sql_aid.PgTable(model.TableByChatFriend).Where("user_id = ?", userId).WhereIn("friend_id", userIds...).ToSql()
	userFriendData, err := sql_aid.DataToMap(model.PgSql.Query(userFriendSql, arge...))
	userFriendDataByKeyData := util.ArrayColumnByInt64(&userFriendData, "friend_id")
	http := os.Getenv("SERVER_HTTP")
	for _, datum := range userData {
		if datum["id"].(int64) == userId {
			datum["is_join"] = 2 //自己
		} else if userFriendDataByKeyData[datum["id"].(int64)] != nil {
			datum["is_join"] = 1 //已经是好友
		} else {
			datum["is_join"] = 0 //不是好友
		}
		datum["avatar"] = util.IsPicturePath(datum["avatar"].(string), http)
	}
	return userData
}

// ChatBySearchGroup 搜索群组
func ChatBySearchGroup(userId int64, search string, page string, pageSize string) []map[string]interface{} {
	GroupSql, args := sql_aid.PgTable(model.TableByChatGroup).Field("id", "name", "master_id", "introduce", "people_number", "time_c", "logo").Where("name like ?", search+"%").PageSize(page, pageSize).ToSql()
	GroupData, err := sql_aid.DataToMap(model.PgSql.Query(GroupSql, args...))
	if err != nil {
		gogo_log.Error("server_ChatBySearchGroup", "查询数据失败", err.Error())
		return []map[string]interface{}{}
	}
	//处理是否已经是好友的信息
	groupIds := util.ArrayField(&GroupData, "id")
	groupFriendSql, args := sql_aid.PgTable(model.TableByChatGroupFriend).Where("user_id = ?", userId).WhereIn("group_id", groupIds...).ToSql()
	groupFriendData, err := sql_aid.DataToMap(model.PgSql.Query(groupFriendSql, args...))
	groupFriendDataByKeyData := util.ArrayColumnByInt64(&groupFriendData, "group_id")
	http := os.Getenv("SERVER_HTTP")
	for _, datum := range GroupData {
		if datum["master_id"].(int64) == userId {
			datum["is_join"] = 2 //自己创建的群组
		} else if groupFriendDataByKeyData[datum["id"].(int64)] != nil {
			datum["is_join"] = 1 //已经在群组
		} else {
			datum["is_join"] = 0 //还未进群组
		}
		datum["logo"] = util.IsPicturePath(datum["logo"].(string), http)
	}
	return GroupData
}

// ChatByApplyFriend 申请好友
func ChatByApplyFriend(userId int64, byUserId int64, content string) error {
	t := time.Now()
	tt := t.Unix()
	tSql := t.Format(time.RFC3339)
	tWs := t.Format("2006-01-02 15:04:05")
	//判断是否已经是好友
	chatFriendSql, args := sql_aid.PgTable(model.TableByChatFriend).Where("user_id = ?", userId).Where("friend_id = ?", byUserId).ToSql()
	chatFriendData, err := sql_aid.DataToMap(model.PgSql.Query(chatFriendSql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyFriend", "用户查询失败", err.Error())
		return errors.New("内部错误")
	}
	if len(chatFriendData) != 0 {
		return errors.New("该用户已经和您是好友关系，无需申请")
	}
	//判断是否已经申请
	applySql, args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).Where("status = ?", model.ChatApplyFriendGroupByStatusWaiting).Where("type_id = ?", model.ChatApplyFriendGroupByTypeIdFriend).Where("user_id = ?", userId).Where("by_user_id = ?", byUserId).ToSql()
	applyData, err := sql_aid.DataToMap(model.PgSql.Query(applySql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyFriend", "申请查询失败", err.Error())
		return errors.New("内部错误")
	}
	if len(applyData) != 0 {
		return errors.New("请勿重复提交")
	}
	//添加消息和加入队列
	tx, err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_ChatByApplyFriend", "事务启动失败", err.Error())
		return errors.New("内部错误")
	}
	defer tx.Rollback()
	var applyId int64
	insertData := make(map[string]interface{})
	insertData["user_id"] = userId
	insertData["type_id"] = model.ChatApplyFriendGroupByTypeIdFriend
	insertData["by_user_id"] = byUserId
	insertData["content"] = content
	insertData["status"] = model.ChatApplyFriendGroupByStatusWaiting
	insertData["refused_message"] = ""
	insertData["time_c"] = tSql
	insertData["time_u"] = tSql
	insertData["merge_user_ids"] = model.ChatApplyFriendGroupByMergeUserIdsToJson(userId, byUserId)
	applySql, args = sql_aid.PgTable(model.TableByChatApplyFriendGroup).InsertByMap(insertData)
	err = tx.QueryRow(applySql+" RETURNING id", args...).Scan(&applyId)
	if err != nil {
		gogo_log.Error("server_ChatByApplyFriend", "添加申请消息错误", err.Error())
		return errors.New("内部错误")
	}
	//推送申请好友消息
	userSlq, args := sql_aid.PgTable(model.TableByUser).Field("id", "nick", "avatar", "motto").Where("id = ?", userId).ToSql()
	userData, err := sql_aid.DataToMap(model.PgSql.Query(userSlq, args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyFriend", "查询用户错误", err.Error())
		return errors.New("内部错误")
	}
	if len(userData) == 0 {
		return errors.New("用户不存在")
	}
	//消息推送
	pushMessage := MessageByStructMain{
		CmdMessage:     MessageByApplyFriend,
		ReceiveUserIds: []interface{}{byUserId, userId},
		SendUserID:     userId,
		SendUser:       userData[0],
		TimeC:          tWs,
		TimeStamp:      tt,
		Content: map[string]interface{}{
			MessageContentByContent: content,
		},
	}
	_ = pushMessage.Push()
	tx.Commit()
	return nil
}

// ChatByApplyGroup 申请进群组
func ChatByApplyGroup(userId int64, groupId int64, content string) error {
	t := time.Now()
	tt := t.Unix()
	tSql := t.Format(time.RFC3339)
	tWs := t.Format("2006-01-02 15:04:05")
	//判断群是否存在
	groupSql, args := sql_aid.PgTable(model.TableByChatGroup).Where("id = ?", groupId).ToSql()
	groupData, err := sql_aid.DataToMap(model.PgSql.Query(groupSql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyGroup", "查询组失败", err.Error())
		return errors.New("内部错误")
	}
	if len(groupData) == 0 {
		return errors.New("群组不存在")
	}
	//判断是否存在群组内
	groupFriendSql, args := sql_aid.PgTable(model.TableByChatGroupFriend).Where("user_id = ?", userId).Where("group_id = ?", groupId).ToSql()
	groupFriendSqlData, err := sql_aid.DataToMap(model.PgSql.Query(groupFriendSql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyGroup", "查询是群组sql失败", err.Error())
		return errors.New("内部错误")
	}
	if len(groupFriendSqlData) != 0 {
		return errors.New("您已经存在与群组，无需申请")
	}
	//判断是否有未审核的
	applyGroupSql, args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).Where("type_id = ?", model.ChatApplyFriendGroupByTypeIdGroup).Where("user_id = ?", userId).Where("group_id = ?", groupId).Where("status = ?", model.ChatApplyFriendGroupByStatusWaiting).ToSql()
	applyGroupData, err := sql_aid.DataToMap(model.PgSql.Query(applyGroupSql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyGroup", "查询申请sql失败", err.Error())
		return errors.New("内部错误")
	}
	if len(applyGroupData) != 0 {
		return errors.New("您已经申请过，无需重复申请")
	}
	//查找组内可审核的成员
	groupFriend := model.ChatGroupFriendByUserCheck(groupId)
	masterUserId := util.ArrayField(&groupFriend,"user_id")
	masterUserId = append(masterUserId, userId)
	//发送进组消息
	insertData := make(map[string]interface{})
	insertData["user_id"] = userId
	insertData["type_id"] = model.ChatApplyFriendGroupByTypeIdGroup
	insertData["by_user_id"] = 0
	insertData["group_id"] = groupId
	insertData["content"] = content
	insertData["status"] = model.ChatApplyFriendGroupByStatusWaiting
	insertData["refused_message"] = ""
	insertData["time_c"] = tSql
	insertData["time_u"] = tSql
	insertData["merge_user_ids"] = model.ChatApplyFriendGroupByMergeUserIdsToJson(masterUserId...)
	insertSql, args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).InsertByMap(insertData)
	_, err = model.PgSql.Exec(insertSql, args...)
	if err != nil {
		gogo_log.Error("server_ChatByApplyGroup", "申请消息失败", err.Error())
		return errors.New("操作失败")
	}

	groupFriendSql, args = sql_aid.PgTable(model.TableByChatGroupFriend).Where("group_id = ?", groupId).WhereIn("identity_id", model.ChatGroupFriendByIdentityIdManager, model.ChatGroupFriendByIdentityIdAdministrator).ToSql()
	groupFriendSqlData, err = sql_aid.DataToMap(model.PgSql.Query(groupFriendSql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyGroup", "查询是群组sql失败", err.Error())
		return errors.New("内部错误")
	}
	//消息推送
	userData, err := model.UserByInfo(userId)
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
		return errors.New("用户不存在")
	}
	masterGroup := util.ArrayField(&groupFriendSqlData, "user_id")
	pushMessage := MessageByStructMain{
		CmdMessage:     MessageByApplyGroup,
		ReceiveUserIds: masterGroup,
		SendUserID:     userId,
		SendUser:       userData,
		TimeC:          tWs,
		TimeStamp:      tt,
		Content: map[string]interface{}{
			MessageContentByContent: content,
		},
	}
	_ = pushMessage.Push()

	return nil
}

// ChatByApplyGroupReverse 邀请进入群组
func ChatByApplyGroupReverse(userId int64, ByUserId int64, groupId int64, content string) error {
	//获取群组信息
	groupData, err := model.ChatGroupByInfo(groupId)
	if err != nil {
		return err
	}
	t := time.Now()
	tt := t.Unix()
	tSql := t.Format(time.RFC3339)
	tWs := t.Format("2006-01-02 15:04:05")

	//检查用户是否已经存在群组
	groupFriendSql, args := sql_aid.PgTable(model.TableByChatGroupFriend).Where("user_id = ?", ByUserId).Where("group_id = ?", groupId).ToSql()
	groupFriendSqlData, err := sql_aid.DataToMap(model.PgSql.Query(groupFriendSql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyGroup", "查询是群组sql失败", err.Error())
		return errors.New("内部错误")
	}
	if len(groupFriendSqlData) >= 1{
		return errors.New("用户已经存在群组")
	}
	groupFriendByIdentity := model.ChatGroupFriendByUserCheck(groupId)
	identityIds := util.ArrayField(&groupFriendByIdentity,"user_id")
	refereesIds := identityIds
	refereesIds = append(refereesIds,ByUserId)
	//添加审核消息
	groupFriendToUserId := util.ArrayField(&groupFriendSqlData, "user_id")
	groupFriendToUserId = append(groupFriendToUserId, ByUserId)
	//发送邀请
	insertData := make(map[string]interface{})
	insertData["user_id"] = ByUserId
	insertData["type_id"] = model.ChatApplyFriendGroupByTypeIdGroupReverse
	insertData["by_user_id"] = 0
	insertData["group_id"] = groupId
	insertData["content"] = content
	insertData["status"] = model.ChatApplyFriendGroupByStatusWaiting
	insertData["refused_message"] = ""
	insertData["time_c"] = tSql
	insertData["time_u"] = tSql
	insertData["merge_user_ids"] = model.ChatApplyFriendGroupByMergeUserIdsToJson(refereesIds...)
	insertData["referees_user_id"] = userId
	var applyId int64
	insertSql, args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).InsertByMap(insertData)
	err = model.PgSql.QueryRow(insertSql+" RETURNING id", args...).Scan(&applyId)
	if err != nil {
		gogo_log.Error("server_ChatByApplyGroup", "申请消息失败", err.Error())
		return errors.New("操作失败")
	}
	insertData["id"] = applyId
	//发送通知
	userData, err := model.UserByInfo(userId)
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
		return errors.New("用户不存在")
	}

	pushMessage := MessageByStructMain{
		CmdMessage:     MessageByApplyGroupReverse,
		ReceiveUserIds: groupFriendToUserId,
		SendUserID:     userId,
		SendUser:       userData,
		TimeC:          tWs,
		TimeStamp:      tt,
		Content: map[string]interface{}{
			MessageContentByContent: content,
			MessageContentByGroup:   groupData,
		},
	}
	_ = pushMessage.Push()
	//检测是否有权限操作,没有则不进行审核，有则直接通过
	groupFriendToKeyUserIdData:= util.ArrayColumnByInt64(&groupFriendByIdentity,"user_id")
	if groupFriendToKeyUserIdData[userId] != nil && groupFriendToKeyUserIdData[userId]["identity_id"].(int64) != model.ChatGroupFriendByIdentityIdOrdinary {
		err = chatByApplyCheckGroupReverse(userId,insertData,model.ChatApplyFriendGroupByStatusAgree,"")
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
			return errors.New(err.Error())
		}
	}
	return nil
}

// ChatByApplyList 申请列表
func ChatByApplyList(userId int64, page string, limit string) []map[string]interface{} {
	applySql, args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).Where("merge_user_ids @> ?", fmt.Sprintf("[{\"user_id\":%v}]", userId)).OrderBy("id desc").PageSize(page, limit).ToSql()
	applyData, err := sql_aid.DataToMap(model.PgSql.Query(applySql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyList", "查询数据失败", err.Error())
		return []map[string]interface{}{}
	}
	//获取申请人的信息
	byUserIds := util.ArrayField(&applyData, "by_user_id")
	userIds := util.ArrayField(&applyData, "user_id")
	userdataByKeyUserId := model.UserByIdsToDataP(&byUserIds, &userIds)
	//获取组信息
	groupIds := util.ArrayField(&applyData, "group_id")
	chatGroupByKeyGroupId := model.ChatGroupToData(groupIds...)

	for _, datum := range applyData {
		if userdataByKeyUserId[datum["by_user_id"].(int64)] != nil {
			datum["by_user"] = userdataByKeyUserId[datum["by_user_id"].(int64)]
		}
		if userdataByKeyUserId[datum["user_id"].(int64)] != nil {
			datum["user"] = userdataByKeyUserId[datum["user_id"].(int64)]
		}
		if chatGroupByKeyGroupId[datum["group_id"].(int64)] != nil {
			datum["group"] = chatGroupByKeyGroupId[datum["group_id"].(int64)]
		}

	}
	return applyData
}

// ChatByApplyCheck 审核申请的消息
func ChatByApplyCheck(userId int64, applyId int64, status int64, content string) error {
	applySql, args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).Where("id = ?", applyId).ToSql()
	applyData, err := sql_aid.DataToMap(model.PgSql.Query(applySql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyCheck", "查询数据失败", err.Error())
		return errors.New("内部错误")
	}
	if len(applyData) == 0 {
		return errors.New("数据不存在")
	}
	if applyData[0]["status"].(int64) != model.ChatApplyFriendGroupByStatusWaiting {
		return errors.New("当前审核已经处理")
	}
	switch applyData[0]["type_id"].(int64) {
	case model.ChatApplyFriendGroupByTypeIdFriend: //加好友
		err = chatByApplyCheckFriend(userId, applyData[0], status, content)
		break
	case model.ChatApplyFriendGroupByTypeIdGroup: //申请加入群
		err = chatByApplyCheckGroup(userId, applyData[0], status, content)
		break
	case model.ChatApplyFriendGroupByTypeIdGroupReverse: //群邀请用户
		err = chatByApplyCheckGroupReverse(userId, applyData[0], status, content)
		break
	default:
		return errors.New("当前数据类型无法处理")
	}
	if err != nil {
		return err
	}
	return nil
}

//审核申请的消息-》申请好友审核
func chatByApplyCheckFriend(userId int64, applyData map[string]interface{}, status int64, content string) error {
	if applyData["by_user_id"].(int64) != userId {
		return errors.New("您无权操作申请")
	}

	t := time.Now()
	tt := t.Unix()
	tSql := t.Format(time.RFC3339)
	tWs := t.Format("2006-01-02 15:04:05")
	tx, err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_ChatByApplyCheck", "事务开启失败", err.Error())
		return errors.New("内部错误")
	}
	defer tx.Rollback()
	//审核表更改状态
	applyUpdate := make(map[string]interface{})
	applyUpdate["status"] = status
	applyUpdate["time_u"] = tSql
	applyUpdate["refused_message"] = content
	applyUpdateSql, args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).Where("id = ?", applyData["id"]).UpdateByMap(applyUpdate)
	_, err = tx.Exec(applyUpdateSql, args...)
	if err != nil {
		gogo_log.Error("server_ChatByApplyCheck", "申请表更改状态失败", err.Error())
		return errors.New("内部错误")
	}
	if status == model.ChatApplyFriendGroupByStatusAgree { //同意进行在数据库中添加
		//查询用户信息
		userIdByUser := model.UserByIdsToData(applyData["user_id"], applyData["by_user_id"])
		friendInserts := make([]map[string]interface{}, 0)
		friendInsert := make(map[string]interface{})
		friendInsert["user_id"] = applyData["user_id"]
		friendInsert["friend_id"] = applyData["by_user_id"]
		if userIdByUser[applyData["by_user_id"].(int64)] != nil {
			friendInsert["friend_note"] = userIdByUser[applyData["by_user_id"].(int64)]["nick"]
		} else {
			friendInsert["friend_note"] = ""
		}
		friendInsert["friend_letter"] = model.ChatFriendByGetFirstLetter(friendInsert["friend_note"].(string))
		friendInsert["time_c"] = t
		friendInserts = append(friendInserts, friendInsert)

		friendInsert = make(map[string]interface{})
		friendInsert["user_id"] = applyData["by_user_id"]
		friendInsert["friend_id"] = applyData["user_id"]
		if userIdByUser[applyData["user_id"].(int64)] != nil {
			friendInsert["friend_note"] = userIdByUser[applyData["user_id"].(int64)]["nick"]
		} else {
			friendInsert["friend_note"] = ""
		}
		friendInsert["friend_letter"] = model.ChatFriendByGetFirstLetter(friendInsert["friend_note"].(string))
		friendInsert["time_c"] = t
		friendInserts = append(friendInserts, friendInsert)
		friendInsertsSql, args := sql_aid.PgTable(model.TableByChatFriend).InsertAllByMap(&friendInserts)
		_, err = tx.Exec(friendInsertsSql, args...)
		if err != nil {
			gogo_log.Error("server_ChatByApplyCheck", "好友表增加失败", err.Error())
			return errors.New("内部错误")
		}
		userMessageInserts := make([]map[string]interface{}, 0)
		userMessageInsert := make(map[string]interface{})
		userMessageInsert["user_id"] = applyData["user_id"]
		userMessageInsert["is_top"] = model.UserMessageByIsTopNo
		userMessageInsert["type_id"] = model.UserMessageByTypeIdFriend
		userMessageInsert["received_id"] = applyData["by_user_id"]
		userMessageInsert["unread_number"] = 0
		userMessageInsert["time_u"] = tSql
		userMessageInsert["status"] = model.UserMessageByStatusShow
		userMessageInsert["chat_message_log_id"] = 0
		userMessageInsert["by_user_id"] = applyData["by_user_id"]
		userMessageInserts = append(userMessageInserts, userMessageInsert)
		userMessageInsert = make(map[string]interface{})
		userMessageInsert["user_id"] = applyData["by_user_id"]
		userMessageInsert["is_top"] = model.UserMessageByIsTopNo
		userMessageInsert["type_id"] = model.UserMessageByTypeIdFriend
		userMessageInsert["received_id"] = applyData["user_id"]
		userMessageInsert["unread_number"] = 0
		userMessageInsert["time_u"] = tSql
		userMessageInsert["status"] = model.UserMessageByStatusShow
		userMessageInsert["chat_message_log_id"] = 0
		userMessageInsert["by_user_id"] = applyData["user_id"]
		userMessageInserts = append(userMessageInserts, userMessageInsert)
		userMessageInsertsSql, args := sql_aid.PgTable(model.TableByUserMessage).InsertAllByMap(&userMessageInserts)
		_, err = tx.Exec(userMessageInsertsSql, args...)
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckFriend", "用户消息表增加失败", err.Error())
			return errors.New("内部错误")
		}
		//消息推送
		userData, err := model.UserByInfo(applyData["by_user_id"].(int64))
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
			return errors.New("用户不存在")
		}
		pushMessage := MessageByStructMain{
			CmdMessage:     MessageByApplyFriendCheckAgree,
			ReceiveUserIds: []interface{}{applyData["user_id"]},
			SendUserID:     applyData["by_user_id"].(int64),
			SendUser:       userData,
			TimeC:          tWs,
			TimeStamp:      tt,
			Content: map[string]interface{}{
				MessageContentByContent: content,
			},
		}
		_ = pushMessage.Push()
	} else {
		//发送拒绝消息
		userData, err := model.UserByInfo(applyData["by_user_id"].(int64))
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
			return errors.New("用户不存在")
		}
		pushMessage := MessageByStructMain{
			CmdMessage:     MessageByApplyFriendCheckRefused,
			ReceiveUserIds: []interface{}{applyData["user_id"]},
			SendUserID:     applyData["by_user_id"].(int64),
			SendUser:       userData,
			TimeC:          tWs,
			TimeStamp:      tt,
			Content: map[string]interface{}{
				MessageContentByContent: content,
			},
		}
		_ = pushMessage.Push()
	}
	tx.Commit()
	return nil

}

//审核申请的消息-》申请进群审核
func chatByApplyCheckGroup(userId int64, applyData map[string]interface{}, status int64, content string) error {
	//不允许自己审核自己的信息
	if applyData["user_id"].(int64) == userId {
		return errors.New("您无法审核自己提交的信息")
	}
	//检测是否有权限操作
	ok := model.ChatApplyFriendGroupByIsMergeUserIds(applyData["merge_user_ids"].(string), userId)
	if ok == false {
		return errors.New("您无权操作申请")
	}
	//群组是否超出最大人员数量
	chatGroupSql, args := sql_aid.PgTable(model.TableByChatGroup).Where("id = ?", applyData["group_id"].(int64)).ToSql()
	chatGroupData, err := sql_aid.DataToMap(model.PgSql.Query(chatGroupSql, args...))
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckGroup", "查询群信息错误", err.Error())
		return errors.New("内部错误")
	}
	if len(chatGroupData) == 0 {
		return errors.New("群组不存在")
	}
	if chatGroupData[0]["people_number"].(int64) >= 1000 {
		return errors.New("群组超出最大人数")
	}
	//给用户加入群组
	tx, err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckGroup", "查询数据失败", err.Error())
		return errors.New("内部错误")
	}
	defer tx.Rollback()
	t := time.Now()
	tt := t.Unix()
	tSql := t.Format(time.RFC3339)
	tWs := t.Format("2006-01-02 15:04:05")
	//申请操作
	applyUpdate := make(map[string]interface{})
	applyUpdate["status"] = status
	applyUpdate["by_user_id"] = userId
	applyUpdate["time_u"] = tSql
	applyUpdate["refused_message"] = content
	applyUpdateSql, args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).Where("id = ?", applyData["id"]).UpdateByMap(applyUpdate)
	_, err = tx.Exec(applyUpdateSql, args...)
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckGroup", "查询数据失败", err.Error())
		return errors.New("内部错误")
	}
	if status == model.ChatApplyFriendGroupByStatusAgree { //同意进行在数据库中添加
		//用户进群
		groupInsert := make(map[string]interface{})
		groupInsert["user_id"] = applyData["user_id"].(int64)
		groupInsert["group_id"] = applyData["group_id"].(int64)
		groupInsert["group_note"] = chatGroupData[0]["name"].(string)
		groupInsert["time_c"] = t
		groupInsert["identity_id"] = model.ChatGroupFriendByIdentityIdOrdinary
		var groupId int64
		groupInsertSql, args := sql_aid.PgTable(model.TableByChatGroupFriend).InsertByMap(groupInsert)
		err = tx.QueryRow(groupInsertSql+" RETURNING id", args...).Scan(&groupId)
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckGroup", "群成员表添加错误", err.Error())
			return errors.New("内部错误")
		}
		//群组人员数量+1
		groupSql, args := sql_aid.PgTable(model.TableByChatGroup).Inc("people_number", 1).UpdateByMap(make(map[string]interface{}))
		_, err = tx.Exec(groupSql, args...)
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckGroup", "群表人员+1错误", err.Error())
			return errors.New("内部错误")
		}
		//增加用户对应得群消息
		userMessageInsert := make(map[string]interface{})
		userMessageInsert["user_id"] = applyData["user_id"].(int64)
		userMessageInsert["is_top"] = model.UserMessageByIsTopNo
		userMessageInsert["type_id"] = model.UserMessageByTypeIdGroup
		userMessageInsert["received_id"] = applyData["group_id"].(int64)
		userMessageInsert["unread_number"] = 0
		userMessageInsert["time_u"] = tSql
		userMessageInsert["status"] = model.UserMessageByStatusShow
		userMessageInsertSql, args := sql_aid.PgTable(model.TableByUserMessage).InsertByMap(userMessageInsert)
		_, err = tx.Exec(userMessageInsertSql, args...)
		//消息推送
		//向群内所有人进行推送
		groupsql, args := sql_aid.PgTable(model.TableByChatGroupFriend).Where("group_id = ?", applyData["group_id"].(int64)).ToSql()
		groupData, _ := sql_aid.DataToMap(tx.Query(groupsql, args...))
		groupUserIds := util.ArrayField(&groupData, "user_id")
		//审核人信息
		userData, err := model.UserByInfo(userId)
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
			return errors.New("用户不存在")
		}
		pushMessage := MessageByStructMain{
			CmdMessage:     MessageByApplyGroupCheckAgree,
			ReceiveUserIds: groupUserIds,
			SendUserID:     userId,
			SendUser:       userData,
			TimeC:          tWs,
			TimeStamp:      tt,
			Content: map[string]interface{}{
				MessageContentByContent: content,
			},
		}
		_ = pushMessage.Push()

	} else {
		//消息推送
		//审核人信息
		userData, err := model.UserByInfo(userId)
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
			return errors.New("用户不存在")
		}
		fmt.Println(applyData["user_id"])
		pushMessage := MessageByStructMain{
			CmdMessage:     MessageByApplyGroupCheckRefused,
			ReceiveUserIds: []interface{}{applyData["user_id"]},
			SendUserID:     userId,
			SendUser:       userData,
			TimeC:          tWs,
			TimeStamp:      tt,
			Content: map[string]interface{}{
				MessageContentByContent: content,
			},
		}
		_ = pushMessage.Push()
	}
	tx.Commit()
	return nil
}

//审核申请的消息-》邀请进群审核
func chatByApplyCheckGroupReverse(userId int64, applyData map[string]interface{}, status int64, content string) error {
	//检测是否有权限操作
	ok := model.ChatApplyFriendGroupByIsMergeUserIds(applyData["merge_user_ids"].(string), userId)
	if ok == false {
		return errors.New("您无权操作申请")
	}
	//群组是否超出最大人员数量
	chatGroupSql, args := sql_aid.PgTable(model.TableByChatGroup).Where("id = ?", applyData["group_id"].(int64)).ToSql()
	chatGroupData, err := sql_aid.DataToMap(model.PgSql.Query(chatGroupSql, args...))
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckGroup", "查询群信息错误", err.Error())
		return errors.New("内部错误")
	}
	if len(chatGroupData) == 0 {
		return errors.New("群组不存在")
	}
	if chatGroupData[0]["people_number"].(int64) >= 1000 {
		return errors.New("群组超出最大人数")
	}
	//给用户加入群组
	tx, err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckGroup", "查询数据失败", err.Error())
		return errors.New("内部错误")
	}
	defer tx.Rollback()
	t := time.Now()
	tt := t.Unix()
	tSql := t.Format(time.RFC3339)
	tWs := t.Format("2006-01-02 15:04:05")
	//申请操作
	applyUpdate := make(map[string]interface{})
	applyUpdate["status"] = status
	applyUpdate["by_user_id"] = userId
	applyUpdate["time_u"] = tSql
	applyUpdate["refused_message"] = content
	applyUpdateSql, args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).Where("id = ?", applyData["id"]).UpdateByMap(applyUpdate)
	_, err = tx.Exec(applyUpdateSql, args...)
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckGroup", "查询数据失败", err.Error())
		return errors.New("内部错误")
	}
	if status == model.ChatApplyFriendGroupByStatusAgree { //同意进行在数据库中添加
		//用户进群
		groupInsert := make(map[string]interface{})
		groupInsert["user_id"] = applyData["user_id"].(int64)
		groupInsert["group_id"] = applyData["group_id"].(int64)
		groupInsert["group_note"] = chatGroupData[0]["name"].(string)
		groupInsert["time_c"] = t
		groupInsert["identity_id"] = model.ChatGroupFriendByIdentityIdOrdinary
		var groupId int64
		groupInsertSql, args := sql_aid.PgTable(model.TableByChatGroupFriend).InsertByMap(groupInsert)
		err = tx.QueryRow(groupInsertSql+" RETURNING id", args...).Scan(&groupId)
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckGroup", "群成员表添加错误", err.Error())
			return errors.New("内部错误")
		}
		//群组人员数量+1
		groupSql, args := sql_aid.PgTable(model.TableByChatGroup).Inc("people_number", 1).UpdateByMap(make(map[string]interface{}))
		_, err = tx.Exec(groupSql, args...)
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckGroup", "群表人员+1错误", err.Error())
			return errors.New("内部错误")
		}
		//增加用户对应得群消息
		userMessageInsert := make(map[string]interface{})
		userMessageInsert["user_id"] = applyData["user_id"].(int64)
		userMessageInsert["is_top"] = model.UserMessageByIsTopNo
		userMessageInsert["type_id"] = model.UserMessageByTypeIdGroup
		userMessageInsert["received_id"] = applyData["group_id"].(int64)
		userMessageInsert["unread_number"] = 0
		userMessageInsert["time_u"] = tSql
		userMessageInsert["status"] = model.UserMessageByStatusShow
		userMessageInsertSql, args := sql_aid.PgTable(model.TableByUserMessage).InsertByMap(userMessageInsert)
		_, err = tx.Exec(userMessageInsertSql, args...)
		//消息推送
		//向群内所有人进行推送
		groupsql, args := sql_aid.PgTable(model.TableByChatGroupFriend).Where("group_id = ?", applyData["group_id"].(int64)).ToSql()
		groupData, _ := sql_aid.DataToMap(tx.Query(groupsql, args...))
		groupUserIds := util.ArrayField(&groupData, "user_id")
		//审核人信息
		userData, err := model.UserByInfo(userId)
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
			return errors.New("用户不存在")
		}
		pushMessage := MessageByStructMain{
			CmdMessage:     MessageByApplyGroupReverseCheckAgree,
			ReceiveUserIds: groupUserIds,
			SendUserID:     userId,
			SendUser:       userData,
			TimeC:          tWs,
			TimeStamp:      tt,
			Content: map[string]interface{}{
				MessageContentByContent: content,
			},
		}
		_ = pushMessage.Push()

	} else {
		//消息推送
		//审核人信息
		userData, err := model.UserByInfo(userId)
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
			return errors.New("用户不存在")
		}
		fmt.Println(applyData["user_id"])
		pushMessage := MessageByStructMain{
			CmdMessage:     MessageByApplyGroupCheckRefused,
			ReceiveUserIds: []interface{}{applyData["user_id"]},
			SendUserID:     userId,
			SendUser:       userData,
			TimeC:          tWs,
			TimeStamp:      tt,
			Content: map[string]interface{}{
				MessageContentByContent: content,
			},
		}
		_ = pushMessage.Push()
	}
	tx.Commit()
	return nil
}

// ChatByFriendList 好友列表
func ChatByFriendList(userId int64, page string, limit string) []map[string]interface{} {
	friendSql, args := sql_aid.PgTable(model.TableByChatFriend).Where("user_id = ?", userId).OrderBy("friend_letter").ToSql()
	friendData, err := sql_aid.DataToMap(model.PgSql.Query(friendSql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByFriendList", "查询数据失败", err.Error())
		return nil
	}
	friendIds := util.ArrayField(&friendData, "friend_id")
	userIdData := model.UserByIdsToData(friendIds...)
	arr := make(map[string][]map[string]interface{}, 0)
	for _, datum := range friendData {
		if userIdData[datum["friend_id"].(int64)] != nil {
			datum["friend"] = userIdData[datum["friend_id"].(int64)]
		}
		arr[datum["friend_letter"].(string)] = append(arr[datum["friend_letter"].(string)], datum)
	}
	dataArr := make([]map[string]interface{}, 0)
	for k, vv := range arr {
		dataMap := make(map[string]interface{})
		dataMap["letter"] = k
		dataMap["data"] = vv
		dataArr = append(dataArr, dataMap)
	}

	return dataArr
}

// ChatByFriendListV2 好友列表
func ChatByFriendListV2(userId int64) []map[string]interface{} {
	friendSql, args := sql_aid.PgTable(model.TableByChatFriend).Where("user_id = ?", userId).OrderBy("friend_letter").ToSql()
	friendData, err := sql_aid.DataToMap(model.PgSql.Query(friendSql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByFriendList", "查询数据失败", err.Error())
		return nil
	}
	friendIds := util.ArrayField(&friendData, "friend_id")
	userIdData := model.UserByIdsToData(friendIds...)
	for _, datum := range friendData {
		if userIdData[datum["friend_id"].(int64)] != nil {
			datum["friend"] = userIdData[datum["friend_id"].(int64)]
		}
	}
	return friendData
}

// ChatByFriendRemove 解除好友关系
func ChatByFriendRemove(userId int64, friendId int64) error {
	if userId == 0 || friendId == 0 {
		return errors.New("缺少参数")
	}
	t := time.Now()
	tt := t.Unix()
	//tSql := t.Format(time.RFC3339)
	tWs := t.Format("2006-01-02 15:04:05")
	tx, err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_ChatByFriendRemove", "事务启动失败", err.Error())
		return errors.New("内部错误")
	}
	defer tx.Rollback()
	friendSql, args := sql_aid.PgTable(model.TableByChatFriend).WhereIn("user_id", userId, friendId).WhereIn("friend_id", userId, friendId).Delete()
	_, err = tx.Exec(friendSql, args...)
	if err != nil {
		gogo_log.Error("server_ChatByFriendRemove", "删除chat_friend数据错误", err.Error())
		return errors.New("内部错误")
	}
	messageSql, args := sql_aid.PgTable(model.TableByUserMessage).Where("type_id = ?", model.UserMessageByTypeIdFriend).WhereIn("user_id", userId, friendId).WhereIn("received_id", userId, friendId).Delete()
	_, err = tx.Exec(messageSql, args...)
	if err != nil {
		gogo_log.Error("server_ChatByFriendRemove", "删除user_message数据错误", err.Error())
		return errors.New("内部错误")
	}
	//发送消息通知
	userData, err := model.UserByInfo(userId)
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
		return errors.New("用户不存在")
	}
	pushMessage := MessageByStructMain{
		CmdMessage:     MessageByApplyFriendRemove,
		ReceiveUserIds: []interface{}{userId, friendId},
		SendUserID:     userId,
		SendUser:       userData,
		TimeC:          tWs,
		TimeStamp:      tt,
		Content:        map[string]interface{}{},
	}
	_ = pushMessage.Push()
	tx.Commit()
	return nil
}

// ChatBySendMessage 发送消息
func ChatBySendMessage(typeId int64, userId int64, receivedId int64, content string) error {
	var err error
	switch typeId {
	case model.ChatMessageLogByTypeIdFriend:
		err = chatBySendMessageFriend(userId, receivedId, content)
		break
	case model.ChatMessageLogByTypeIdGroup:
		err = chatBySendMessageGroup(userId, receivedId, content)
		break
	default:
		return errors.New("未找到对应功能")
	}
	if err != nil {
		return err
	}
	return nil
}

//发送消息->发送好友
func chatBySendMessageFriend(userId int64, receivedId int64, content string) error {

	t := time.Now()
	tt := t.Unix()
	tSql := t.Format(time.RFC3339)
	tWs := t.Format("2006-01-02 15:04:05")
	friendSql, args := sql_aid.PgTable(model.TableByChatFriend).Where("user_id = ?", receivedId).Where("friend_id = ?", userId).ToSql()
	friendData, err := sql_aid.DataToMap(model.PgSql.Query(friendSql, args...))
	if err != nil {
		gogo_log.Error("server_chatBySendMessageFriend", "查询数据失败", err.Error())
		return errors.New("内部错误")
	}
	if len(friendData) == 0 {
		return errors.New("对方还不是您的好友")
	}
	tx, err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_chatBySendMessageFriend", "事务启动失败", err.Error())
		return errors.New("内部错误")
	}
	defer tx.Rollback()
	var chatMessageLogId int64
	insertMessage := make(map[string]interface{})
	insertMessage["send_user_id"] = userId
	insertMessage["type_id"] = model.ChatMessageLogByTypeIdFriend
	insertMessage["received_id"] = receivedId
	insertMessage["content"] = content
	insertMessage["fallback_user_id"] = 0
	insertMessage["time_c"] = tSql
	insertMessageSql, args := sql_aid.PgTable(model.TableByChatMessageLog).InsertByMap(insertMessage)
	err = tx.QueryRow(insertMessageSql+" RETURNING id", args...).Scan(&chatMessageLogId)
	//_,err = tx.Exec(insertMessageSql,args...)
	if err != nil {
		gogo_log.Error("server_chatBySendMessageFriend", "消息添加错误", err.Error())
		return errors.New("内部错误")
	}
	//消息内容
	userMessageUpdate := make(map[string]interface{})
	userMessageUpdate["time_u"] = tSql
	userMessageUpdate["status"] = model.UserMessageByStatusShow
	userMessageUpdate["chat_message_log_id"] = chatMessageLogId
	userMessageUpdate["by_user_id"] = receivedId
	//发给用户消息
	userMessageUpdateSql, args := sql_aid.PgTable(model.TableByUserMessage).Where("type_id = ?", model.UserMessageByTypeIdFriend).WhereIn("user_id", receivedId, userId).WhereIn("received_id", userId, receivedId).Inc("unread_number", 1).UpdateByMap(userMessageUpdate)
	_, err = tx.Exec(userMessageUpdateSql, args...)
	if err != nil {
		gogo_log.Error("server_chatBySendMessageFriend", "更改发送用户消息错误", err.Error())
		return errors.New("内部错误")
	}
	//发送消息通知
	userData, err := model.UserByInfo(userId)
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
		return errors.New("用户不存在")
	}
	pushMessage := MessageByStructMain{
		CmdMessage:     MessageByOnlyChat,
		ReceiveUserIds: []interface{}{userId, receivedId},
		SendUserID:     userId,
		SendUser:       userData,
		TimeC:          tWs,
		TimeStamp:      tt,
		Content: map[string]interface{}{
			MessageContentByContent:       content,
			MessageContentBySendMessageId: chatMessageLogId,
		},
	}
	_ = pushMessage.Push()
	tx.Commit()
	return nil

}

//发送消息->发送群
func chatBySendMessageGroup(userId int64, groupId int64, content string) error {
	t := time.Now()
	tt := t.Unix()
	tSql := t.Format(time.RFC3339)
	tWs := t.Format("2006-01-02 15:04:05")
	//验证用户是否存在于群组
	groupFriendSql, args := sql_aid.PgTable(model.TableByChatGroupFriend).Where("user_id = ?", userId).Where("group_id = ?", groupId).ToSql()
	groupFriendData, err := sql_aid.DataToMap(model.PgSql.Query(groupFriendSql, args...))
	if err != nil {
		gogo_log.Error("server_chatBySendMessageFriend", "查询数据失败", err.Error())
		return errors.New("内部错误")
	}
	if len(groupFriendData) == 0 {
		return errors.New("请线加入群组")
	}
	//获取群组信息
	groupData, err := model.ChatGroupByInfo(groupId)
	if err != nil {
		return err
	}
	tx, err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_chatBySendMessageFriend", "事务启动失败", err.Error())
		return errors.New("内部错误")
	}
	defer tx.Rollback()
	var chatMessageLogId int64
	insertMessage := make(map[string]interface{})
	insertMessage["send_user_id"] = userId
	insertMessage["type_id"] = model.ChatMessageLogByTypeIdGroup
	insertMessage["received_id"] = groupId
	insertMessage["content"] = content
	insertMessage["fallback_user_id"] = 0
	insertMessage["time_c"] = t
	insertMessageSql, args := sql_aid.PgTable(model.TableByChatMessageLog).InsertByMap(insertMessage)
	err = tx.QueryRow(insertMessageSql+" RETURNING id", args...).Scan(&chatMessageLogId)
	if err != nil {
		gogo_log.Error("server_chatBySendMessageFriend", "消息添加错误", err.Error())
		return errors.New("内部错误")
	}
	//消息内容
	userMessageUpdate := make(map[string]interface{})
	userMessageUpdate["time_u"] = tSql
	userMessageUpdate["status"] = model.UserMessageByStatusShow
	userMessageUpdate["chat_message_log_id"] = chatMessageLogId
	userMessageUpdate["by_user_id"] = userId
	//发给用户消息
	userMessageUpdateSql, args := sql_aid.PgTable(model.TableByUserMessage).Where("type_id = ?", model.UserMessageByTypeIdGroup).Where("received_id = ?", groupId).Inc("unread_number", 1).UpdateByMap(userMessageUpdate)
	_, err = tx.Exec(userMessageUpdateSql, args...)
	if err != nil {
		gogo_log.Error("server_chatBySendMessageFriend", "更改发送用户消息错误", err.Error())
		return errors.New("内部错误")
	}

	//发送消息通知
	userData, err := model.UserByInfo(userId)
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
		return errors.New("用户不存在")
	}
	//群组所有成员
	groupFriendSql, args = sql_aid.PgTable(model.TableByChatGroupFriend).Field("user_id").Where("group_id = ?", groupId).ToSql()
	groupFriendData, err = sql_aid.DataToMap(model.PgSql.Query(groupFriendSql, args...))
	if err != nil {
		gogo_log.Error("server_chatBySendMessageFriend", "查询数据失败", err.Error())
		return errors.New("内部错误")
	}
	groupFriendDataToUserId := util.ArrayField(&groupFriendData, "user_id")
	pushMessage := MessageByStructMain{
		CmdMessage:     MessageByGroupChat,
		ReceiveUserIds: groupFriendDataToUserId,
		SendUserID:     userId,
		SendUser:       userData,
		TimeC:          tWs,
		TimeStamp:      tt,
		Content: map[string]interface{}{
			MessageContentByContent:       content,
			MessageContentByGroup:         groupData,
			MessageContentBySendMessageId: chatMessageLogId,
		},
	}
	_ = pushMessage.Push()
	tx.Commit()
	return nil
}

// ChatByCreateGroup 创建群
func ChatByCreateGroup(userId int64, name string, introduce string, logo string) (map[string]interface{}, error) {
	t := time.Now()
	tSql := t.Format(time.RFC3339)
	//tWs := t.Format("2006-01-02 15:04:05")
	tx, err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_ChatByCreateGroup", "事务启动失败", err.Error())
		return nil, errors.New("内部错误")
	}
	defer tx.Rollback()
	//群组头像
	if len(logo) != 0 {
		logoPath := strings.Replace(logo, os.Getenv("SERVER_HTTP"), "", -1)       //去除域名
		logo = strings.Replace(logoPath, "common", model.ChatGroupByLogoPath, -1) //从common移出后则不会再删除
		_, _ = utility.CopyFile("."+logo, "."+logoPath)
	}
	insertGroup := make(map[string]interface{})
	insertGroup["master_id"] = userId
	insertGroup["name"] = name
	insertGroup["introduce"] = introduce
	insertGroup["people_number"] = 1
	insertGroup["time_c"] = t
	insertGroup["logo"] = logo
	var groupId int64
	insertGroupSql, args := sql_aid.PgTable(model.TableByChatGroup).InsertByMap(insertGroup)
	err = tx.QueryRow(insertGroupSql+" RETURNING id", args...).Scan(&groupId)
	if err != nil {
		gogo_log.Error("server_ChatByCreateGroup", "创建群失败", err.Error())
		return nil, errors.New("内部错误")
	}
	insertGroupFriend := make(map[string]interface{})
	insertGroupFriend["user_id"] = userId
	insertGroupFriend["group_id"] = groupId
	insertGroupFriend["group_note"] = name
	insertGroupFriend["time_c"] = t
	insertGroupFriend["identity_id"] = model.ChatGroupFriendByIdentityIdManager
	insertGroupFriendSql, args := sql_aid.PgTable(model.TableByChatGroupFriend).InsertByMap(insertGroupFriend)
	_, err = tx.Exec(insertGroupFriendSql, args...)
	if err != nil {
		gogo_log.Error("server_ChatByCreateGroup", "添加组信息失败", err.Error())
		return nil, errors.New("内部错误")
	}
	insertUserMessage := make(map[string]interface{})
	insertUserMessage["user_id"] = userId
	insertUserMessage["is_top"] = model.UserMessageByIsTopNo
	insertUserMessage["type_id"] = model.UserMessageByTypeIdGroup
	insertUserMessage["received_id"] = groupId
	insertUserMessage["unread_number"] = 0
	insertUserMessage["time_u"] = tSql
	insertUserMessage["status"] = model.UserMessageByStatusShow
	insertUserMessage["chat_message_log_id"] = 0
	insertUserMessage["by_user_id"] = 0
	insertUserMessageSql, args := sql_aid.PgTable(model.TableByUserMessage).InsertByMap(insertUserMessage)
	_, err = tx.Exec(insertUserMessageSql, args...)
	if err != nil {
		gogo_log.Error("server_ChatByCreateGroup", "添加用户消息错误", err.Error())
		return nil, errors.New("内部错误")
	}
	tx.Commit()
	insertGroup["id"] = groupId
	return insertGroup, nil
}

// ChatByGroupList 群组列表
func ChatByGroupList(userId int64, page string, limit string) []map[string]interface{} {
	groupSql, args := sql_aid.PgTable(model.TableByChatGroupFriend).Where("user_id = ?", userId).PageSize(page, limit).ToSql()
	groupData, err := sql_aid.DataToMap(model.PgSql.Query(groupSql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByGroupList", "查询数据失败", err.Error())
		return nil
	}
	groupIds := util.ArrayField(&groupData, "group_id")
	groupIdData := model.ChatGroupToData(groupIds...)
	for _, datum := range groupData {
		if groupIdData[datum["group_id"].(int64)] != nil {
			datum["group"] = groupIdData[datum["group_id"].(int64)]
		}
	}
	return groupData
}

// ChatByGroupFriendList 群组成员列表
func ChatByGroupFriendList(userId int64, groupId int64, page string, limit string)[]map[string]interface{}{
	groupFriendSql, args := sql_aid.PgTable(model.TableByChatGroupFriend).Field("id","user_id","identity_id","member_name").Where("group_id = ?", groupId).PageSize(page, limit).ToSql()
	groupFriendData, err := sql_aid.DataToMap(model.PgSql.Query(groupFriendSql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByGroupFriend", "查询数据失败", err.Error())
		return nil
	}
	userIds := util.ArrayField(&groupFriendData,"user_id")
	userData := model.UserByIdsToData(userIds...)
	for _, val := range groupFriendData {
		if userData[val["user_id"].(int64)] != nil {
			val["user"] = userData[val["user_id"].(int64)]
		}else{
			val["user"] = nil
		}
	}
	return groupFriendData
}

// ChatByGroupInfo 群组成员列表
func ChatByGroupInfo(userId int64, groupId int64)(map[string]interface{},error){
	groupFriendSql, args := sql_aid.PgTable(model.TableByChatGroupFriend).Where("group_id = ?", groupId).Where("user_id = ?",userId).ToSql()
	groupFriendData, err := sql_aid.DataToMap(model.PgSql.Query(groupFriendSql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByGroupInfo", "查询数据失败", err.Error())
		return nil,errors.New("内部错误")
	}
	if len(groupFriendData) < 1{
		return nil,errors.New("您不在当前群组，无法查看")
	}
	groupData, err := model.ChatGroupByInfo(groupId)
	if err != nil {
		gogo_log.Error("server_ChatByGroupInfo", "查询数据失败", err.Error())
		return nil,errors.New("内部错误")
	}
	if len(groupData) < 1{
		return nil,errors.New("您不在当前群组，无法查看")
	}
	data := make(map[string]interface{})
	data["group"] = groupData
	data["group_friend_self"] = groupFriendData[0]
	return data,nil
}

// ChatByCreateGroupDelete 解散群组
func ChatByCreateGroupDelete(userId int64, groupId int64) error {
	if userId == 0 || groupId == 0 {
		return errors.New("缺少参数")
	}

	//只有群主可以操作
	groupCheckSql, args := sql_aid.PgTable(model.TableByChatGroup).Where("id = ?", groupId).Where("user_id = ?", userId).ToSql()
	groupData, err := sql_aid.DataToMap(model.PgSql.Query(groupCheckSql, args...))
	if err != nil || len(groupData) <= 0 {
		return errors.New("只有群主可操作")
	}
	tx, err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_ChatByCreateGroupDelete", "事务启动失败", err.Error())
		return errors.New("内部错误")
	}
	defer tx.Rollback()
	t := time.Now()
	tt := t.Unix()
	//tSql := t.Format(time.RFC3339)
	tWs := t.Format("2006-01-02 15:04:05")
	//删除群组
	groupSql, args := sql_aid.PgTable(model.TableByChatGroup).Where("id = ?", groupId).Delete()
	_, err = tx.Exec(groupSql, args...)
	if err != nil {
		gogo_log.Error("server_ChatByCreateGroupDelete", "删除chat_group错误", err.Error())
		return errors.New("内部错误")
	}
	//删除群组成员
	groupFriendSql, args := sql_aid.PgTable(model.TableByChatGroupFriend).Where("group_id = ?", groupId).Delete()
	_, err = tx.Exec(groupFriendSql, args...)
	if err != nil {
		gogo_log.Error("server_ChatByCreateGroupDelete", "删除chat_group_friend错误", err.Error())
		return errors.New("内部错误")
	}
	//删除用户消息对应组信息
	userMessageSql, args := sql_aid.PgTable(model.TableByUserMessage).Where("type_id = ?", model.UserMessageByTypeIdGroup).Where("received_id = ?", groupId).Delete()
	_, err = tx.Exec(userMessageSql, args...)
	if err != nil {
		gogo_log.Error("server_ChatByCreateGroupDelete", "删除user_message错误", err.Error())
		return errors.New("内部错误")
	}
	//发消息
	userData, err := model.UserByInfo(userId)
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
		return errors.New("用户不存在")
	}
	pushMessage := MessageByStructMain{
		CmdMessage:     MessageByApplyGroupDelete,
		ReceiveUserIds: model.ChatGroupFriendByGroupAllUserId(groupId), //群组所有成员
		SendUserID:     userId,
		SendUser:       userData,
		TimeC:          tWs,
		TimeStamp:      tt,
		Content: map[string]interface{}{
			MessageContentByGroup: groupData,
		},
	}
	_ = pushMessage.Push()
	tx.Commit()
	return nil
}

// ChatByCreateGroupExit 退出群组
func ChatByCreateGroupExit(userId int64, groupId int64) error {
	if userId == 0 || groupId == 0 {
		return errors.New("缺少参数")
	}
	//群主无法退出群组
	groupCheckSql, args := sql_aid.PgTable(model.TableByChatGroup).Where("id = ?", groupId).Where("user_id = ?", userId).ToSql()
	groupData, err := sql_aid.DataToMap(model.PgSql.Query(groupCheckSql, args...))
	if err != nil || len(groupData) > 0 {
		return errors.New("群主无法退出群")
	}
	tx, err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_ChatByCreateGroupExit", "事务启动失败", err.Error())
		return errors.New("内部错误")
	}
	defer tx.Rollback()
	t := time.Now()
	tt := t.Unix()
	//tSql := t.Format(time.RFC3339)
	tWs := t.Format("2006-01-02 15:04:05")
	//从群人员表中吧自己删除
	groupFriendSql, args := sql_aid.PgTable(model.TableByChatGroupFriend).Where("user_id = ?", userId).Where("group_id = ?", groupId).Delete()
	_, err = tx.Exec(groupFriendSql, args...)
	if err != nil {
		gogo_log.Error("server_ChatByCreateGroupExit", "删除group_friend数据错误", err.Error())
		return errors.New("内部错误")
	}
	//对应群组人数-1
	groupSql, args := sql_aid.PgTable(model.TableByChatGroup).Where("id = ?", groupId).Dec("people_number", 1).UpdateByMap(map[string]interface{}{})
	_, err = tx.Exec(groupSql, args...)
	if err != nil {
		gogo_log.Error("server_ChatByCreateGroupExit", "修改group数据错误", err.Error())
		return errors.New("内部错误")
	}
	//删除我的消息对应的群组信息
	userMessageSql, args := sql_aid.PgTable(model.TableByUserMessage).Where("type_id = ?", model.UserMessageByTypeIdGroup).Where("user_id = ?", userId).Where("received_id = ?", groupId).Delete()
	_, err = tx.Exec(userMessageSql, args...)
	if err != nil {
		gogo_log.Error("server_ChatByCreateGroupExit", "删除user_message数据错误", err.Error())
		return errors.New("内部错误")
	}
	//发送消息通知
	userData, err := model.UserByInfo(userId)
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
		return errors.New("用户不存在")
	}
	pushMessage := MessageByStructMain{
		CmdMessage:     MessageByApplyGroupRemove,
		ReceiveUserIds: model.ChatGroupFriendByGroupAllUserId(groupId), //群组所有成员
		SendUserID:     userId,
		SendUser:       userData,
		TimeC:          tWs,
		TimeStamp:      tt,
		Content: map[string]interface{}{
			MessageContentByGroup: groupData,
		},
	}
	_ = pushMessage.Push()
	tx.Commit()
	return nil
}

// ChatByCleanMessage 消除接收到得消息
func ChatByCleanMessage(userId int64, userMessageId int64) error {
	tx, err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_ChatByCleanMessage", "事务启动失败", err.Error())
		return errors.New("内部错误")
	}
	defer tx.Rollback()
	t := time.Now()
	tt := t.Unix()
	//tSql := t.Format(time.RFC3339)
	tWs := t.Format("2006-01-02 15:04:05")
	dataUpdate := make(map[string]interface{})
	dataUpdate["unread_number"] = 0
	dataSql, args := sql_aid.PgTable(model.TableByUserMessage).Where("user_id = ?", userId).WhereRaw(func(query *sql_aid.PgQuery, i ...interface{}) {
		if i[0].(int64) != 0 {
			query.Where("id = ?", i[0])
		}
	}, userMessageId).UpdateByMap(dataUpdate)
	_, err = tx.Exec(dataSql, args...)
	if err != nil {
		gogo_log.Error("server_ChatByCleanMessage", "清理消息条数失败", err.Error())
		return errors.New("操作失败")
	}
	//发送消息通知
	pushMessage := MessageByStructMain{
		CmdMessage:     MessageByApplyUserMessageClean,
		ReceiveUserIds: []interface{}{userId},
		TimeC:          tWs,
		TimeStamp:      tt,
		Content: map[string]interface{}{
			MessageContentByContent: userMessageId,
		},
	}
	_ = pushMessage.Push()

	tx.Commit()
	return nil
}

// ChatByMessageIsTopYes 消息置顶
func ChatByMessageIsTopYes(userId int64, messageId int64) error {
	updateData := make(map[string]interface{})
	updateData["is_top"] = model.UserMessageByIsTopYes
	userMessageSql, args := sql_aid.PgTable(model.TableByUserMessage).Where("user_id = ?", userId).Where("id = ?", messageId).UpdateByMap(updateData)
	_, err := model.PgSql.Exec(userMessageSql, args...)
	if err != nil {
		gogo_log.Error("server_ChatByMessageIsTopYes", "更改失败", err.Error())
		return errors.New("操作失败")
	}
	t := time.Now()
	tt := t.Unix()
	//tSql := t.Format(time.RFC3339)
	tWs := t.Format("2006-01-02 15:04:05")
	pushMessage := MessageByStructMain{
		CmdMessage:     MessageByApplyUserMessageIsTopYes,
		ReceiveUserIds: []interface{}{userId},
		SendUserID:     userId,
		SendUser:       nil,
		TimeC:          tWs,
		TimeStamp:      tt,
		Content: map[string]interface{}{
			MessageContentByContent: messageId,
		},
	}
	_ = pushMessage.Push()
	return nil
}

func ChatByMessageIsTopNo(userId int64, messageId int64) error {

	updateData := make(map[string]interface{})
	updateData["is_top"] = model.UserMessageByIsTopNo
	userMessageSql, args := sql_aid.PgTable(model.TableByUserMessage).Where("user_id = ?", userId).Where("id = ?", messageId).UpdateByMap(updateData)
	_, err := model.PgSql.Exec(userMessageSql, args...)
	if err != nil {
		gogo_log.Error("server_ChatByMessageIsTopNo", "更改失败", err.Error())
		return errors.New("操作失败")
	}
	t := time.Now()
	tt := t.Unix()
	//tSql := t.Format(time.RFC3339)
	tWs := t.Format("2006-01-02 15:04:05")
	pushMessage := MessageByStructMain{
		CmdMessage:     MessageByApplyUserMessageIsTopNo,
		ReceiveUserIds: []interface{}{userId},
		SendUserID:     userId,
		SendUser:       nil,
		TimeC:          tWs,
		TimeStamp:      tt,
		Content: map[string]interface{}{
			MessageContentByContent: messageId,
		},
	}
	_ = pushMessage.Push()

	return nil
}

func ChatByMessageList(typeId int64, userId int64, receivedId int64, page string, pageSize string) []map[string]interface{} {
	if typeId == model.ChatMessageLogByTypeIdFriend { //好友信息

		return chatByMessageListFriend(userId, receivedId, page, pageSize)
	} else if typeId == model.ChatMessageLogByTypeIdGroup {
		return []map[string]interface{}{}
	} else {
		return []map[string]interface{}{}
	}

}

func chatByMessageListFriend(userId int64, receivedId int64, page string, pageSize string) []map[string]interface{} {
	userByUserId := model.UserByIdsToData(userId, receivedId)
	messageSql, arge := sql_aid.PgTable(model.TableByChatMessageLog).Where("type_id = ?", model.ChatMessageLogByTypeIdFriend).WhereIn("send_user_id", userId, receivedId).WhereIn("received_id", userId, receivedId).OrderBy("id desc").PageSize(page, pageSize).ToSql()
	messageData, err := sql_aid.DataToMap(model.PgSql.Query(messageSql, arge...))
	if err != nil {
		return []map[string]interface{}{}
	}
	for _, v := range messageData {
		if userByUserId[v["send_user_id"].(int64)] != nil {
			v["user"] = userByUserId[v["send_user_id"].(int64)]
		} else {
			v["user"] = nil
		}
	}
	return messageData
}
